#pragma once

#include <MyFC/ListControl.h>
#include "DLL.h"

namespace My {

/**
 * A row that can be expanded/collapsed.
 * Displays a triangular button beside its caption.
 */
class DLL_API ExpandableRow : public virtual Row {
public:
	ExpandableRow();
public:
	virtual String GetCaption() const = 0;
	virtual bool CanExpand() const = 0;
	virtual bool IsExpanded() const = 0;
	virtual void Expand() = 0;
	virtual void Collapse() = 0;
public:
	virtual void HandlePaint(CDC *, const CRect &);
	virtual void HandleLeftDoubleClick(unsigned int flags, const CPoint & p);
	virtual void HandleLeftDown(unsigned int flags, const CPoint & p);
protected:
	virtual My::Size GetLevel() const { return 0; }
	void PaintCaption(CDC *, const CRect &);
protected:
	My::Size	m_Indent;
	CRect		m_ButtonRect;
};

/** 
 * A row that has child rows. 
 */
class DLL_API TreeRow : public ExpandableRow 
{
	friend class Tree;
public:
	TreeRow();
public:
	TreeRow * GetParentRow() const
		{ return m_pParentRow; }
	bool IsEmpty() const;
	My::Size GetChildCount() const;
	TreeRow & GetChild(My::Size) const;
	void Append(TreeRow * pRow) 
		{ Insert(GetChildCount(), &pRow, 1); }
	void Insert(My::Size pos, TreeRow * pRow)
		{ Insert(pos, &pRow, 1); }
	void Insert(My::Size pos, TreeRow * rows[], My::Size count);
	void Remove(My::Size pos, My::Size count = 1);
	void Clear();
	void SetVisible(bool);
public:
	My::Size CountRows(bool countSelf = true) const;
	My::Size EnumerateRows(Row * [], My::Size, bool enumSelf = true);
public:
	virtual bool CanExpand() const;
	virtual bool IsExpanded() const;
	virtual void Expand();
	virtual void Collapse();
protected:
	virtual My::Size GetLevel() const;
private:
	TreeRow *				m_pParentRow;
	std::vector<TreeRow *>	m_Children;
	bool					m_Expanded;
};


class DLL_API Tree : protected virtual List 
{
	friend class TreeRow;
public:
	Tree(ScrollBox &);
public:
	bool IsEmpty() const;
	My::Size GetRowCount() const;
	TreeRow & GetRow(My::Size) const;
	using List::GetVisibleRowCount;
	using List::GetVisibleRow;
	using List::GetTotalHeight;
	void Append(TreeRow * pRow) 
		{ Insert(GetRowCount(), &pRow, 1); }
	void Insert(My::Size pos, TreeRow * pRow)
		{ Insert(pos, &pRow, 1); }
	void Insert(My::Size pos, TreeRow * rows[], My::Size count);
	void Remove(My::Size pos, My::Size count = 1);
	void Clear();
protected:
	std::vector<TreeRow *>	m_Rows;
};


} // My